package cn.fz.utils;

import cn.hutool.crypto.asymmetric.SM2;
import lombok.Getter;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class SM2Example2 {
    /**
     * 私钥签名
     */
    public static String SM2Signature(String data, String priKey) {
        SM2 sm2 = new SM2(ByteUtils.fromHexString(priKey), null);
        // 对数据进行签名，并将签名结果Base64编码
        return Base64.getEncoder().encodeToString(sm2.sign(data.getBytes(StandardCharsets.UTF_8)));
    }

    /**
     * 公钥验签
     */
    public static boolean SM2SigVerifier(String data, String sig, String pubKey) {
        SM2 sm2 = new SM2(null, ByteUtils.fromHexString(pubKey));
        // 验证签名
        return sm2.verify(data.getBytes(StandardCharsets.UTF_8), Base64.getDecoder().decode(sig));
    }


    // 生成SM2公私钥对，并设置密文数据顺序为老标准 C1C2C3
    public static KeyPair generateSM2KeyPair() {
        SM2 sm2 = new SM2();
        // 设置密文数据顺序为老标准 C1C2C3
        // sm2.setCipher('C', '1', 'C', '2', 'C', '3');
        sm2.setMode(SM2Engine.Mode.C1C2C3);

        // 获取公钥和私钥
        String privateKey = sm2.getPrivateKeyBase64();
        String publicKey = sm2.getPublicKeyBase64();

        return new KeyPair(publicKey, privateKey);
    }

    // 提供外部获取公钥的接口
    public static String getPublicKey(KeyPair keyPair) {
        return keyPair.getPublicKey();
    }

    // 用于存储公私钥对的简单结构
    @Getter
    public static class KeyPair {
        private final String publicKey;
        private final String privateKey;

        public KeyPair(String publicKey, String privateKey) {
            this.publicKey = publicKey;
            this.privateKey = privateKey;
        }

    }

    public static void main(String[] args) {
        // 调用生成公私钥对的方法
        KeyPair keyPair = generateSM2KeyPair();
        System.out.println("生成的私钥：" + keyPair.getPrivateKey());
        System.out.println("生成的公钥：" + keyPair.getPublicKey());

        // 使用提供的接口获取公钥
        String publicKey = getPublicKey(keyPair);
        System.out.println("通过接口获取的公钥：" + publicKey);

        // 剩余的签名、验签逻辑...

        // 签名数据
        String data = "hello";
        String signature = SM2Signature(data, keyPair.getPrivateKey());
        System.out.println("签名结果：" + signature);

        // URL编码签名结果
        String signUrlEncode = java.net.URLEncoder.encode(signature, StandardCharsets.UTF_8);
        System.out.println("URL编码后的签名：" + signUrlEncode);

        // 验签
        boolean isVerify = SM2SigVerifier(data, signature, keyPair.getPublicKey());
        System.out.println("验签结果：" + isVerify);
    }
}
